package net.bezrabotnih.cabinet.client.app;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.google.gwt.activity.shared.ActivityManager;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.logging.client.LogConfiguration;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.requestfactory.client.RequestFactoryLogHandler;
import com.google.gwt.requestfactory.shared.LoggingRequest;
import com.google.gwt.requestfactory.shared.Receiver;
import com.google.gwt.requestfactory.shared.ServerFailure;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.HasConstrainedValue;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.inject.Inject;

import net.bezrabotnih.cabinet.client.activity.MasterActivityMapper;
import net.bezrabotnih.cabinet.client.place.FirstTimeLoginPlace;
import net.bezrabotnih.cabinet.client.place.MainMenuItemPicker;
import net.bezrabotnih.cabinet.client.place.MenuItemPlace;
import net.bezrabotnih.cabinet.client.place.PerformerMainMenuItemPlace;
import net.bezrabotnih.cabinet.client.place.PerformerMainPlace;
import net.bezrabotnih.cabinet.client.place.ProfileEditPlace;
import net.bezrabotnih.cabinet.client.place.ProfilePlace;
import net.bezrabotnih.cabinet.client.place.ProviderMainMenuItemPlace;
import net.bezrabotnih.cabinet.client.place.ProviderMainPlace;
import net.bezrabotnih.cabinet.client.request.CabinetRequestFactory;
import net.bezrabotnih.cabinet.client.ui.ApplicationDesktopShell;
import net.bezrabotnih.client.managed.request.UserAccountProxy;
import net.bezrabotnih.client.scaffold.ScaffoldDesktopShell;
import net.bezrabotnih.client.scaffold.gae.GaeLoginWidgetDriver;
import net.bezrabotnih.client.scaffold.request.RequestEvent;


/**
 * 
 * application for desktop
 * 
 * @author Stan
 *
 */

public class DesktopApplication extends Application{
	
	private static final Logger log = Logger.getLogger(DesktopApplication.class.getName());
	private final ApplicationDesktopShell shell;
	private final CabinetRequestFactory requestFactory;
	private final EventBus eventBus;
	private final PlaceController placeController;
	private final MasterActivityMapper masterActivityMapper;
	
	
	@Inject
	public DesktopApplication(ApplicationDesktopShell shell,CabinetRequestFactory requestFactory,EventBus eventBus,PlaceController placeController,MasterActivityMapper masterActivityMapper) {
		this.shell=shell;
		this.requestFactory=requestFactory;
		this.eventBus=eventBus;
		this.placeController=placeController;
		this.masterActivityMapper=masterActivityMapper;
	}
	
	
	
	 @Override
	public void run() {
		 /* Add handlers, setup activities */
			init();

			/* Hide the loading message */
			Element loading = Document.get().getElementById("loading");
			loading.getParentElement().removeChild(loading);
	        new GaeLoginWidgetDriver(requestFactory).setWidget(shell.getLoginWidget());
			/* And show the user the shell */
	        RootPanel.get("site").add(shell);
		 
	}
	 
	 
	 @SuppressWarnings("deprecation")
	private void init() {
			GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() {
				public void onUncaughtException(Throwable e) {
					Window.alert("Error: " + e.getMessage());
					log.log(Level.SEVERE, e.getMessage(), e);
				}
			});

			if (LogConfiguration.loggingIsEnabled()) {
				// Add remote logging handler
				RequestFactoryLogHandler.LoggingRequestProvider provider = new RequestFactoryLogHandler.LoggingRequestProvider() {
					public LoggingRequest getLoggingRequest() {
						return requestFactory.loggingRequest();
					}
				};
				Logger.getLogger("").addHandler(new RequestFactoryLogHandler(provider, Level.WARNING, new ArrayList<String>()));
			}

			RequestEvent.register(eventBus, new RequestEvent.Handler() {
				// Only show loading status if a request isn't serviced in 250ms.
				private static final int LOADING_TIMEOUT = 250;

				public void onRequestEvent(RequestEvent requestEvent) {
					if (requestEvent.getState() == RequestEvent.State.SENT) {
						shell.getMole().showDelayed(LOADING_TIMEOUT);
					} else {
						shell.getMole().hide();
					}
				}
			});
	
		//-----------------------------
			
			final ActivityManager masterActivityManager=new ActivityManager(masterActivityMapper, eventBus);
			masterActivityManager.setDisplay(shell.getMasterPanel());
			
			final MainMenuItemPicker mainMenuItemPicker=new MainMenuItemPicker(placeController);
			HasConstrainedValue<MenuItemPlace> menuPickerView=shell.getPlacesBox();
			mainMenuItemPicker.register(eventBus,menuPickerView);
			
			mainMenuItemPicker.setProviderView();
			
			
			
			
			requestFactory.cabinetLoginActionRequest().hasLoggedInFirstTime().fire(new Receiver<Boolean>() {

				@Override
				public void onSuccess(final Boolean hasLoggedinFirstTime) {
					
					requestFactory.cabinetUserAccountRequest().currentUserAccount().fire(new Receiver<UserAccountProxy>() {
						@Override
						public void onSuccess(UserAccountProxy currentUser) {
							if (currentUser!=null){
								final boolean isPerformer=(currentUser.getAccountType()==0); 
								if (isPerformer){
									mainMenuItemPicker.setPerformerView();
								} else{
									mainMenuItemPicker.setProviderView();
								}
								final Place firstPlace=hasLoggedinFirstTime?new ProfileEditPlace():isPerformer?new PerformerMainPlace():new ProviderMainPlace();
								placeController.goTo(firstPlace);
								
							}else{
								//TODO currentUser==null
							}
						}
						@Override
						public void onFailure(ServerFailure error) {
							System.out.println(error.getExceptionType());
							System.out.println(error.getMessage());
						}
					});
					
					
					
				}
			});
			
			
			
			
			
		//------------------------------	
			
	 }

}
